﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MNH.WebApps.Common.Helpers.JqGrid
{
    public class Column
    {
        private readonly List<string> _classes = new List<string>();
        private bool? _resizeable = new bool?(false);
        private List<string> _searchOptions = new List<string>();
        private readonly string _columnName;
        private Align? _align;
        public string _gridId;
        private string _customFormatter;
        private SortOrder? _firstSortOrder;
        private bool? _fixedWidth;
        private KeyValuePair<Formatters, string>? _formatter;
        private bool? _hidden;
        private string _index;
        private bool? _key;
        private string _label;
        private bool? _search;
        private bool? _clearSearch;
        private string _searchDateFormat;
        private IDictionary<string, string> _searchTerms;
        private Searchtype? _searchType;
        private bool? _sortable;
        private bool? _title;
        private int? _width;
        private string _defaultSearchValue;
        private bool? _expandableInTree;
        private bool? _editable;
        private EditType? _editType;
        private EditOptions _editOptions;
        private EditRules _editRules;
        private EditFormOptions _editFormOptions;
        private SortType? _sortType;

        internal string Index
        {
            get
            {
                return this._index;
            }
        }

        internal bool HasDefaultSearchValue
        {
            get
            {
                return !StringExtensions.IsNullOrWhiteSpace(this._defaultSearchValue);
            }
        }

        internal string DefaultSearchValue
        {
            get
            {
                return this._defaultSearchValue;
            }
        }

        public bool IsKey
        {
            get
            {
                bool? nullable = this._key;
                return nullable.HasValue && nullable.GetValueOrDefault();
            }
        }

        public bool IsExpandable
        {
            get
            {
                bool? nullable = this._expandableInTree;
                return nullable.HasValue && nullable.GetValueOrDefault();
            }
        }

        public string Name
        {
            get
            {
                return this._columnName;
            }
        }

        internal string SearchOption
        {
            get
            {
                return Enumerable.Any<string>((IEnumerable<string>)this._searchOptions) ? Enumerable.First<string>((IEnumerable<string>)this._searchOptions) : "cn";
            }
        }

        public Column(string columnName)
        {
            if (StringExtensions.IsNullOrWhiteSpace(columnName))
                throw new ArgumentException("No columnname specified");
            if (Enumerable.Contains<string>((IEnumerable<string>)new string[3]
      {
        "subgrid",
        "cb",
        "rn"
      }, columnName))
                throw new ArgumentException("Columnname '" + columnName + "' is reserved");
            this._columnName = columnName;
            this._index = columnName;
        }

        public Column AddClass(string className)
        {
            this._classes.Add(className);
            return this;
        }

        public Column SetSearchDateFormat(string searchDateFormat)
        {
            this._searchDateFormat = searchDateFormat;
            return this;
        }

        public Column SetSearchTerms(string[] searchTerms)
        {
            this._searchTerms = (IDictionary<string, string>)Enumerable.ToDictionary<string, string>((IEnumerable<string>)searchTerms, (Func<string, string>)(searchterm => searchterm));
            return this;
        }

        public Column SetClearSearch(bool clearSearch)
        {
            this._clearSearch = new bool?(clearSearch);
            return this;
        }

        public Column SetSearchTerms(IDictionary<string, string> searchTerms)
        {
            this._searchTerms = searchTerms;
            return this;
        }

        public Column SetAlign(Align align)
        {
            this._align = new Align?(align);
            return this;
        }

        public Column SetFirstSortOrder(SortOrder firstSortOrder)
        {
            this._firstSortOrder = new SortOrder?(firstSortOrder);
            return this;
        }

        public Column SetFixedWidth(bool fixedWidth)
        {
            this._fixedWidth = new bool?(fixedWidth);
            return this;
        }

        public Column SetFormatter(Formatters formatter)
        {
            if (!StringExtensions.IsNullOrWhiteSpace(this._customFormatter))
                throw new Exception("You cannot set a formatter and a customformatter at the same time, please choose one.");
            this._formatter = new KeyValuePair<Formatters, string>?(new KeyValuePair<Formatters, string>(formatter, ""));
            return this;
        }

        public Column SetFormatter(Formatters formatter, string formatOptions)
        {
            if (!StringExtensions.IsNullOrWhiteSpace(this._customFormatter))
                throw new Exception("You cannot set a formatter and a customformatter at the same time, please choose one.");
            this._formatter = new KeyValuePair<Formatters, string>?(new KeyValuePair<Formatters, string>(formatter, formatOptions));
            return this;
        }

        public Column SetCustomFormatter(string customFormatter)
        {
            if (this._formatter.HasValue)
                throw new Exception("You cannot set a formatter and a customformatter at the same time, please choose one.");
            this._customFormatter = customFormatter;
            return this;
        }

        public Column SetHidden(bool hidden)
        {
            this._hidden = new bool?(hidden);
            return this;
        }

        public Column SetIndex(string index)
        {
            this._index = index;
            return this;
        }

        public Column SetKey(bool key)
        {
            this._key = new bool?(key);
            return this;
        }

        public Column SetLabel(string label)
        {
            this._label = label;
            return this;
        }

        public Column SetResizeable(bool resizeable)
        {
            this._resizeable = new bool?(resizeable);
            return this;
        }

        public Column SetSearch(bool search)
        {
            this._search = new bool?(search);
            return this;
        }

        public Column SetSearchType(Searchtype searchType)
        {
            this._searchType = new Searchtype?(searchType);
            return this;
        }

        public Column SetSortable(bool sortable)
        {
            this._sortable = new bool?(sortable);
            return this;
        }

        public Column SetTitle(bool title)
        {
            this._title = new bool?(title);
            return this;
        }

        public Column SetWidth(int width)
        {
            this._width = new int?(width);
            return this;
        }

        public Column SetDefaultSearchValue(string defaultSearchValue)
        {
            this._defaultSearchValue = defaultSearchValue;
            return this;
        }

        public Column SetAsExpandable()
        {
            this._expandableInTree = new bool?(true);
            return this;
        }

        public Column SetSearchOption(List<SearchOptions> searchOptions)
        {
            foreach (SearchOptions searchOption in searchOptions)
            {
                switch (searchOption)
                {
                    case SearchOptions.DoesNotEndWith:
                        this._searchOptions.Add("en");
                        break;
                    case SearchOptions.Contains:
                        this._searchOptions.Add("cn");
                        break;
                    case SearchOptions.DoesNotContain:
                        this._searchOptions.Add("nc");
                        break;
                    case SearchOptions.IsIn:
                        this._searchOptions.Add("in");
                        break;
                    case SearchOptions.IsNotIn:
                        this._searchOptions.Add("ni");
                        break;
                    case SearchOptions.EndsWith:
                        this._searchOptions.Add("ew");
                        break;
                    case SearchOptions.GreaterOrEqual:
                        this._searchOptions.Add("ge");
                        break;
                    case SearchOptions.BeginsWith:
                        this._searchOptions.Add("bw");
                        break;
                    case SearchOptions.DoesNotBeginWith:
                        this._searchOptions.Add("bn");
                        break;
                    case SearchOptions.Equal:
                        this._searchOptions.Add("eq");
                        break;
                    case SearchOptions.NotEqual:
                        this._searchOptions.Add("ne");
                        break;
                    case SearchOptions.Less:
                        this._searchOptions.Add("lt");
                        break;
                    case SearchOptions.LessOrEqual:
                        this._searchOptions.Add("le");
                        break;
                    case SearchOptions.Greater:
                        this._searchOptions.Add("gt");
                        break;
                }
            }
            return this;
        }

        public Column SetEditable(bool editable)
        {
            this._editable = new bool?(editable);
            return this;
        }

        public Column SetEditType(EditType editType)
        {
            this._editType = new EditType?(editType);
            return this;
        }

        public Column SetEditOptions(EditOptions editOptions)
        {
            this._editOptions = editOptions;
            return this;
        }

        public Column SetEditRules(EditRules editRules)
        {
            this._editRules = editRules;
            return this;
        }

        public Column SetEditFormOptions(EditFormOptions editFormOptions)
        {
            this._editFormOptions = editFormOptions;
            return this;
        }

        public Column SetSortType(SortType sortType)
        {
            this._sortType = new SortType?(sortType);
            return this;
        }

        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("{").AppendLine();
            if (this._align.HasValue)
                stringBuilder.AppendFormat("align:'{0}',", (object)this._align.ToString().ToLower()).AppendLine();
            if (this._classes.Count > 0)
                stringBuilder.AppendFormat("classes:'{0}',", (object)string.Join(" ", Enumerable.ToArray<string>(Enumerable.Select<string, string>((IEnumerable<string>)this._classes, (Func<string, string>)(c => c))))).AppendLine();
            stringBuilder.AppendFormat("name:'{0}',", (object)this._columnName).AppendLine();
            if (this._firstSortOrder.HasValue)
                stringBuilder.AppendFormat("firstsortorder:'{0}',", (object)this._firstSortOrder.ToString().ToLower()).AppendLine();
            if (this._fixedWidth.HasValue)
                stringBuilder.AppendFormat("fixed:{0},", (object)this._fixedWidth.Value.ToString().ToLower()).AppendLine();
            if (this._formatter.HasValue && StringExtensions.IsNullOrWhiteSpace(this._formatter.Value.Value))
                stringBuilder.AppendFormat("formatter:'{0}',", (object)((object)this._formatter.Value.Key).ToString().ToLower()).AppendLine();
            if (this._formatter.HasValue && !StringExtensions.IsNullOrWhiteSpace(this._formatter.Value.Value))
                stringBuilder.AppendLine("formatter:'" + ((object)this._formatter.Value.Key).ToString().ToLower() + "', formatoptions: {" + this._formatter.Value.Value + "},");
            if (!StringExtensions.IsNullOrWhiteSpace(this._customFormatter))
                stringBuilder.AppendFormat("formatter:{0},", (object)this._customFormatter).AppendLine();
            if (this._hidden.HasValue)
                stringBuilder.AppendFormat("hidden:{0},", (object)this._hidden.Value.ToString().ToLower()).AppendLine();
            if (this._key.HasValue)
                stringBuilder.AppendFormat("key:{0},", (object)this._key.Value.ToString().ToLower()).AppendLine();
            if (!StringExtensions.IsNullOrWhiteSpace(this._label))
                stringBuilder.AppendFormat("label:'{0}',", (object)this._label).AppendLine();
            if (this._resizeable.HasValue)
                stringBuilder.AppendFormat("resizable:{0},", (object)this._resizeable.Value.ToString().ToLower()).AppendLine();
            if (this._search.HasValue)
                stringBuilder.AppendFormat("search:{0},", (object)this._search.Value.ToString().ToLower()).AppendLine();
            if (this._sortable.HasValue)
                stringBuilder.AppendFormat("sortable:{0},", (object)this._sortable.Value.ToString().ToLower()).AppendLine();
            if (this._title.HasValue)
                stringBuilder.AppendFormat("title:{0},", (object)this._title.Value.ToString().ToLower()).AppendLine();
            if (this._width.HasValue)
                stringBuilder.AppendFormat("width:{0},", (object)this._width.Value).AppendLine();
            if (this._editable.HasValue)
                stringBuilder.AppendFormat("editable:{0},", (object)this._editable.Value.ToString().ToLower()).AppendLine();
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            if (this._searchType.HasValue)
            {
                if (this._searchType.Value == Searchtype.Text)
                    stringBuilder.AppendLine("stype:'text',");
                if (this._searchType.Value == Searchtype.Select)
                    stringBuilder.AppendLine("stype:'select',");
                if (Enumerable.Any<string>((IEnumerable<string>)this._searchOptions))
                    dictionary.Add("sopt", string.Format("['{0}']", (object)Enumerable.Aggregate<string>((IEnumerable<string>)this._searchOptions, (Func<string, string, string>)((current, next) => current + "',  '" + next))));
                else
                    dictionary.Add("sopt", "['cn']");
            }
            Searchtype? nullable = this._searchType;
            int num;
            if ((nullable.GetValueOrDefault() != Searchtype.Select ? 0 : (nullable.HasValue ? 1 : 0)) == 0)
            {
                nullable = this._searchType;
                num = (nullable.GetValueOrDefault() != Searchtype.Datepicker ? 0 : (nullable.HasValue ? 1 : 0)) == 0 ? 1 : 0;
            }
            else
                num = 0;
            if (num == 0)
            {
                nullable = this._searchType;
                if ((nullable.GetValueOrDefault() != Searchtype.Select ? 0 : (nullable.HasValue ? 1 : 0)) != 0)
                {
                    if (this._searchTerms != null)
                    {
                        string str = Enumerable.Any<KeyValuePair<string, string>>((IEnumerable<KeyValuePair<string, string>>)this._searchTerms) ? ":;" : ":";
                        dictionary.Add("value", "\"" + string.Format("{0}{1}", (object)str, (object)string.Join(";", Enumerable.ToArray<string>(Enumerable.Select<KeyValuePair<string, string>, string>((IEnumerable<KeyValuePair<string, string>>)this._searchTerms, (Func<KeyValuePair<string, string>, string>)(s => s.Key + ":" + s.Value))))) + "\"");
                    }
                    else
                        dictionary.Add("value", "':'");
                }
                nullable = this._searchType;
                if ((nullable.GetValueOrDefault() != Searchtype.Datepicker ? 0 : (nullable.HasValue ? 1 : 0)) != 0)
                {
                    if (StringExtensions.IsNullOrWhiteSpace(this._searchDateFormat))
                        dictionary.Add("dataInit", "function(el){ $(document).ready(function () { Calendar.setup({ inputField:$(el).attr('id') ,button:$(el).attr('id'),ifFormat: \"%Y-%m-%d\",dateType: 'jalali',weekNumbers: false });  $(el).blur(function(e){ $(\"#" + _gridId + "\")[0].triggerToolbar(); });  });   }");
                    else
                        dictionary.Add("dataInit", "function(el){$(document).ready(function () { Calendar.setup({ inputField:$(el).attr('id') ,button:$(el).attr('id'),ifFormat:'" + this._searchDateFormat + "',dateType: 'jalali',weekNumbers: false});}); }");
                }
            }
            if (this._searchType.HasValue && !StringExtensions.IsNullOrWhiteSpace(this._defaultSearchValue))
                dictionary.Add("defaultValue", "'" + this._defaultSearchValue + "'");
            if (!this._searchType.HasValue && !StringExtensions.IsNullOrWhiteSpace(this._defaultSearchValue))
                dictionary.Add("defaultValue", "'" + this._defaultSearchValue + "'");
            if (this._clearSearch.HasValue)
                dictionary.Add("clearSearch", this._clearSearch.Value.ToString().ToLower());
            if (Enumerable.Any<string>((IEnumerable<string>)this._searchOptions) && !this._searchType.HasValue)
                dictionary.Add("sopt", "['" + Enumerable.Aggregate<string>((IEnumerable<string>)this._searchOptions, (Func<string, string, string>)((current, next) => current + "', '" + next)) + "']");
            if (Enumerable.Any<KeyValuePair<string, string>>((IEnumerable<KeyValuePair<string, string>>)dictionary))
                stringBuilder.AppendLine("searchoptions: { " + string.Join(", ", Enumerable.Select<KeyValuePair<string, string>, string>((IEnumerable<KeyValuePair<string, string>>)dictionary, (Func<KeyValuePair<string, string>, string>)(x => x.Key + ":" + x.Value))) + " },");
            if (this._editType.HasValue)
                stringBuilder.AppendFormat("edittype:'{0}',", (object)((object)this._editType.Value).ToString().ToLower()).AppendLine();
            if (this._editOptions != null)
                stringBuilder.AppendFormat("editoptions:{0},", (object)this._editOptions.ToString()).AppendLine();
            if (this._editRules != null)
                stringBuilder.AppendFormat("editrules:{0},", (object)this._editRules.ToString()).AppendLine();
            if (this._editFormOptions != null)
                stringBuilder.AppendFormat("formoptions:{0},", (object)this._editFormOptions.ToString()).AppendLine();
            if (this._sortType.HasValue)
                stringBuilder.AppendFormat("sorttype:'{0}',", (object)this._sortType.ToString().ToLower()).AppendLine();
            stringBuilder.AppendFormat("index:'{0}'", (object)this._index).AppendLine();
            stringBuilder.Append("}");
            return ((object)stringBuilder).ToString();
        }
    }
}
